#include "ClientComm.h"
#include "Command.h"

ClientComm::ClientComm()
{
	NonBlocking = false;
    ConnectSocket = INVALID_SOCKET;
    result = NULL;
    ptr = NULL;
    recvbuflen = DEFAULT_BUFLEN;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if(iResult != 0) {	printf("WSAStartup failed with error: %d\n", iResult);	return;}

    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
}

ClientComm::~ClientComm()
{
    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();
}

bool ClientComm::Send(Command* Cmd)
{
	if(Cmd->getCmdType() == SSpawn)
		if(!Connect(Cmd))
			return false;

	Cmd->Pack(recvbuf);

	iResult = send( ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0 );
	if (iResult == SOCKET_ERROR) {	printf("send failed with error: %d\n", WSAGetLastError());	closesocket(ConnectSocket);	WSACleanup();	return false;}
	
	iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
	if(iResult < 0)	{	printf("recv failed with error: %d\n", WSAGetLastError());	closesocket(ConnectSocket);	WSACleanup();	return false;}

	Cmd->unPack(recvbuf);

	if(Cmd->getCmdType() == RQuit)
		return false;

	return true;
}

bool ClientComm::Connect(Command* Cmd)
{
	// Resolve the server address and port
	iResult = getaddrinfo(Cmd->getString(), DEFAULT_PORT, &hints, &result);
    if(iResult != 0) {	printf("getaddrinfo failed with error: %d\n", iResult);	WSACleanup();	return false;}

	// Attempt to connect to an address until one succeeds
	for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) 
	{
		// Create a SOCKET for connecting to server
		ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
		if (ConnectSocket == INVALID_SOCKET) {	printf("socket failed with error: %ld\n", WSAGetLastError());	WSACleanup();	return false;}

		
		//Make Blocking
		iResult = ioctlsocket(ConnectSocket, FIONBIO, &NonBlocking);
		if (iResult != NO_ERROR)	printf("ioctlsocket failed with error: %ld\n", iResult);

		// Connect to server.
		iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
		if (iResult == SOCKET_ERROR) {	closesocket(ConnectSocket);	ConnectSocket = INVALID_SOCKET;	continue;}
		break;
	}

    freeaddrinfo(result);
    if (ConnectSocket == INVALID_SOCKET) {	printf("Unable to connect to server!\n");	WSACleanup();	return false;}

	return true;
}